Android -handler源码解析
Jan 20, 2018
Looper 源码解析
|
|
消息循环 Loop()方法
|
|
Handler 源码
|
|
发送消息
send的发送方法:sendMessage()
12345678910111213141516171819202122232425262728293031323334353637383940414243444546public final boolean sendMessage(Message msg){return sendMessageDelayed(msg, 0);}//我们往下扒public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {Message msg = Message.obtain();msg.what = what;return sendMessageDelayed(msg, delayMillis);}public final boolean sendMessageDelayed(Message msg, long delayMillis){if (delayMillis < 0) {delayMillis = 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);}public boolean sendMessageAtTime(Message msg, long uptimeMillis) {//直接获取MessageQueueMessageQueue queue = mQueue;if (queue == null) {RuntimeException e = new RuntimeException(this + " sendMessageAtTime() called with no mQueue");Log.w("Looper", e.getMessage(), e);return false;}//调用了enqueueMessage方法return enqueueMessage(queue, msg, uptimeMillis);}//调用sendMessage方法其实最后是调用了enqueueMessage方法private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {//为msg.target赋值为this,也就是把当前的handler作为msg的target属性//如果大家还记得Looper的loop()方法会取出每个msg然后执行msg.target.dispatchMessage(msg)去处理消息,其实就是派发给相应的Handlermsg.target = this;if (mAsynchronous) {msg.setAsynchronous(true);}//最终调用queue的enqueueMessage的方法,也就是说handler发出的消息,最终会保存到消息队列中去。return queue.enqueueMessage(msg, uptimeMillis);}Post 发送消息
12345678showhandler.post(new Runnable() {public void run() {String line = "\n";StringBuffer text = new StringBuffer(show.getText());text.append(line).append("angelababy:Yes,I do");show.setText(text);}dispathMessage()
123456789101112131415public void dispatchMessage(Message msg) {if (msg.callback != null) {handleCallback(msg);} else {if (mCallback != null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}}public void handleMessage(Message msg) {}
在Activity启动应用的时候
|
|
MessageQueue 入队
|
|
MessageQueue出队
|
|
ThreadLocal
线程本地存储区(Thread Local Storage,简称为TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。TLS常用的操作方法
ThreadLocal.set(T value):将value存储到当前线程的TLS区域,源码如下:
12345678910public void set(T value) {Thread currentThread = Thread.currentThread(); //获取当前线程Values values = values(currentThread); //查找当前线程的本地储存区if (values == null) {//当线程本地存储区,尚未存储该线程相关信息时,则创建Values对象values = initializeValues(currentThread);}//保存数据value到当前线程thisvalues.put(this, value);}ThreadLocal.get():获取当前线程TLS区域的数据,源码如下:
12345678910111213141516171819public T get() {Thread currentThread = Thread.currentThread();//获取当前线程Values values = values(currentThread);//查找当前线程的本地储存区if (values != null) {Object[] table = values.table;int index = hash & values.mask;if (this.reference == table[index]) {return (T) table[index + 1];//返回当前线程储存区中的数据}} else {//创建Values对象values = initializeValues(currentThread);}return (T) values.getAfterMiss(this);//从目标线程存储区没有查询是则返回null}